package com.itheima.before_leyou_store.demo;

import com.alibaba.fastjson.JSON;
import com.itheima.before_leyou_store.pojo.User;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;


import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.Stats;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class Demo2 {
    private RestHighLevelClient client;
    @Test
    public void SearchAll() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery());

        SearchRequest request =new SearchRequest("user");
        request.source(sourceBuilder);


      parseResponse(request);

    }

    @Test
    public void searchByQuery() throws IOException {
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("node","传智播客学表演"));

        SearchRequest searchRequest = new SearchRequest("user");
        searchRequest.source(sourceBuilder);
        parseResponse(searchRequest);
    }

    @Test
    public void searchByTerm() throws IOException {
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery("node","唱歌"));

        SearchRequest request =new SearchRequest("user");
        request.source(sourceBuilder);

        parseResponse(request);
        

    }

    @Test
    public void fuzzySearch() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("node","javass").fuzziness("2"));
        SearchRequest request =new SearchRequest("user");
        request.source(sourceBuilder);
        parseResponse(request);
    }

    @Test
    public void rangeSearch() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.rangeQuery("age").gte(10).lte(20));
        SearchRequest request = new SearchRequest("user");
        request.source(sourceBuilder);
        parseResponse(request);
    }

    @Test
    public void boolQuery() throws IOException {
        SearchSourceBuilder sourceBuilder = new  SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("node","唱歌")).mustNot(QueryBuilders.rangeQuery("age").gte(10).lte(20)));
        SearchRequest searchRequest =new SearchRequest("user");
         searchRequest.source(sourceBuilder);
         parseResponse(searchRequest);
    }


    @Test
    public void searchAndSort() throws IOException {
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery()).sort("age",SortOrder.DESC);


        sourceBuilder.sort("age", SortOrder.ASC);
        SearchRequest request = new SearchRequest("user");
        request.source(sourceBuilder);
        parseResponse(request);

    }

    @Test
    public void pageQuery() throws IOException {
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery()).sort("age",SortOrder.DESC).from(0).size(3);


        sourceBuilder.sort("age", SortOrder.ASC);
        SearchRequest request = new SearchRequest("user");
        request.source(sourceBuilder);
        parseResponse(request);

    }
    

    @Test
    public void highlightQuery() throws IOException {
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("node","唱歌"))
                .sort("age",SortOrder.DESC)
                .from(0).size(3)
                .highlighter(new HighlightBuilder().field("node").preTags("<cm>").postTags("</cm>"));
        SearchRequest request = new SearchRequest("user");
        request.source(sourceBuilder);
        parseResponse(request);

    }

    @Test
    public void Aggregation() throws IOException {
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.from(0).size(0);
        sourceBuilder.aggregation(AggregationBuilders.terms("gender").field("gender")
                .subAggregation(AggregationBuilders.stats("age").field("age")));
        SearchRequest request = new SearchRequest("user");
        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        Aggregations aggregations = response.getAggregations();
        Terms gender = aggregations.get("gender");
        List<? extends Terms.Bucket> buckets = gender.getBuckets();

        for (Terms.Bucket bucket : buckets) {
            String keyAsString = bucket.getKeyAsString();
            System.out.println(keyAsString);
            long docCountError = bucket.getDocCount();
            System.out.println(docCountError);
            Aggregations aggregations1 = bucket.getAggregations();
            Stats age = aggregations1.get("age");
            System.out.println("最小值为"+age.getMin());
            System.out.println("最大值为"+age.getMax());
            System.out.println("平均值为"+age.getAvg());
            System.out.println("总值为"+age.getSum());

        }

    }

    private void parseResponse(SearchRequest request) throws IOException {
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        TotalHits totalHits = hits.getTotalHits();
        System.out.println("totalHits = " + totalHits);
        float maxScore = hits.getMaxScore();
        System.out.println("maxScore = " + maxScore);
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {


            float score = hitsHit.getScore();
            System.out.println("score = " + score);
            String hitSourceAsString = hitsHit.getSourceAsString();
            User user = JSON.parseObject(hitSourceAsString, User.class);
            Map<String, HighlightField> highlightFields = hitsHit.getHighlightFields();
            if (highlightFields!=null&&!highlightFields.isEmpty()){
                HighlightField node = highlightFields.get("node");
                Text[] fragments = node.getFragments();
                String join = StringUtils.join(fragments);
                user.setNode(join);

            }
            System.out.println(user);
        }
    }
    




    @Before
    public void createRestHighLevelClient(){
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.187.128", 9200, "http")));

    }


    @After
    public void closeRestHighLevelClient() throws Exception {
        client.close();
    }
}
